home *** CD-ROM | disk | FTP | other *** search
Text File | 2004-04-18 | 55.0 KB | 2,046 lines |
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is The JavaScript Debugger.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Robert Ginda, <rginda@netscape.com>, original author
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
- const JSD_CTRID = "@mozilla.org/js/jsd/debugger-service;1";
- const jsdIDebuggerService = Components.interfaces.jsdIDebuggerService;
- const jsdIExecutionHook = Components.interfaces.jsdIExecutionHook;
- const jsdIErrorHook = Components.interfaces.jsdIErrorHook;
- const jsdICallHook = Components.interfaces.jsdICallHook;
- const jsdIValue = Components.interfaces.jsdIValue;
- const jsdIProperty = Components.interfaces.jsdIProperty;
- const jsdIScript = Components.interfaces.jsdIScript;
- const jsdIStackFrame = Components.interfaces.jsdIStackFrame;
-
- const TYPE_VOID = jsdIValue.TYPE_VOID;
- const TYPE_NULL = jsdIValue.TYPE_NULL;
- const TYPE_BOOLEAN = jsdIValue.TYPE_BOOLEAN;
- const TYPE_INT = jsdIValue.TYPE_INT;
- const TYPE_DOUBLE = jsdIValue.TYPE_DOUBLE;
- const TYPE_STRING = jsdIValue.TYPE_STRING;
- const TYPE_FUNCTION = jsdIValue.TYPE_FUNCTION;
- const TYPE_OBJECT = jsdIValue.TYPE_OBJECT;
-
- const PROP_ENUMERATE = jsdIProperty.FLAG_ENUMERATE;
- const PROP_READONLY = jsdIProperty.FLAG_READONLY;
- const PROP_PERMANENT = jsdIProperty.FLAG_PERMANENT;
- const PROP_ALIAS = jsdIProperty.FLAG_ALIAS;
- const PROP_ARGUMENT = jsdIProperty.FLAG_ARGUMENT;
- const PROP_VARIABLE = jsdIProperty.FLAG_VARIABLE;
- const PROP_EXCEPTION = jsdIProperty.FLAG_EXCEPTION;
- const PROP_ERROR = jsdIProperty.FLAG_ERROR;
- const PROP_HINTED = jsdIProperty.FLAG_HINTED;
-
- const SCRIPT_NODEBUG = jsdIScript.FLAG_DEBUG;
- const SCRIPT_NOPROFILE = jsdIScript.FLAG_PROFILE;
-
- const COLLECT_PROFILE_DATA = jsdIDebuggerService.COLLECT_PROFILE_DATA;
-
- const PCMAP_SOURCETEXT = jsdIScript.PCMAP_SOURCETEXT;
- const PCMAP_PRETTYPRINT = jsdIScript.PCMAP_PRETTYPRINT;
-
- const RETURN_CONTINUE = jsdIExecutionHook.RETURN_CONTINUE;
- const RETURN_CONT_THROW = jsdIExecutionHook.RETURN_CONTINUE_THROW;
- const RETURN_VALUE = jsdIExecutionHook.RETURN_RET_WITH_VAL;
- const RETURN_THROW = jsdIExecutionHook.RETURN_THROW_WITH_VAL;
-
- const FTYPE_STD = 0;
- const FTYPE_SUMMARY = 1;
- const FTYPE_ARRAY = 2;
-
- const BREAKPOINT_STOPNEVER = 0;
- const BREAKPOINT_STOPALWAYS = 1;
- const BREAKPOINT_STOPTRUE = 2;
- const BREAKPOINT_EARLYRETURN = 3;
-
- var $ = new Array(); /* array to store results from evals in debug frames */
-
- function compareVersion(maj, min)
- {
- if (console.jsds.implementationMajor < maj)
- return -1;
-
- if (console.jsds.implementationMajor > maj)
- return 1;
-
- if (console.jsds.implementationMinor < min)
- return -1;
-
- if (console.jsds.implementationMinor > min)
- return 1;
-
- return 0;
- }
-
- function initDebugger()
- {
- dd ("initDebugger {");
-
- console.instanceSequence = 0;
- console._continueCodeStack = new Array(); /* top of stack is the default */
- /* return code for the most */
- /* recent debugTrap(). */
- console.scriptWrappers = new Object();
- console.scriptManagers = new Object();
- console.breaks = new Object();
- console.fbreaks = new Object();
- console.sbreaks = new Object();
-
- /* create the debugger instance */
- if (!(JSD_CTRID in Components.classes))
- throw new BadMojo (ERR_NO_DEBUGGER);
-
- console.jsds =
- Components.classes[JSD_CTRID].getService(jsdIDebuggerService);
- console.jsds.on();
-
- if (compareVersion(1, 2) >= 0)
- console.jsds.flags = jsdIDebuggerService.DISABLE_OBJECT_TRACE;
-
- console.executionHook = { onExecute: jsdExecutionHook };
- console.errorHook = { onError: jsdErrorHook };
- console.callHook = { onCall: jsdCallHook };
-
- console.jsdConsole = console.jsds.wrapValue(console);
-
- dispatch ("tmode", {mode: console.prefs["lastThrowMode"]});
- dispatch ("emode", {mode: console.prefs["lastErrorMode"]});
-
- var enumer = { enumerateScript: console.scriptHook.onScriptCreated };
- console.jsds.scriptHook = console.scriptHook;
- console.jsds.enumerateScripts(enumer);
-
- console.jsds.breakpointHook = console.executionHook;
- console.jsds.debuggerHook = console.executionHook;
- console.jsds.debugHook = console.executionHook;
- console.jsds.errorHook = console.errorHook;
-
- console.jsds.flags = jsdIDebuggerService.ENABLE_NATIVE_FRAMES;
-
- dd ("} initDebugger");
- }
-
- function detachDebugger()
- {
- if ("frames" in console)
- console.jsds.exitNestedEventLoop();
-
- var b;
- for (b in console.breaks)
- console.breaks[b].clearBreakpoint();
- for (b in console.fbreaks)
- console.fbreaks[b].clearFutureBreakpoint();
-
- console.jsds.topLevelHook = null;
- console.jsds.functionHook = null;
- console.jsds.breakpointHook = null;
- console.jsds.debuggerHook = null;
- console.jsds.errorHook = null;
- console.jsds.scriptHook = null;
- console.jsds.interruptHook = null;
- console.jsds.clearAllBreakpoints();
-
- console.jsds.GC();
-
- if (!console.jsds.initAtStartup)
- console.jsds.off();
- }
-
- console.scriptHook = new Object();
-
- console.scriptHook.onScriptCreated =
- function sh_created (jsdScript)
- {
- try
- {
- jsdScriptCreated(jsdScript);
- }
- catch (ex)
- {
- dd ("caught " + dumpObjectTree(ex) + " while creating script.");
- }
- }
-
- console.scriptHook.onScriptDestroyed =
- function sh_destroyed (jsdScript)
- {
- try
- {
- jsdScriptDestroyed(jsdScript);
- }
- catch (ex)
- {
- dd ("caught " + dumpObjectTree(ex) + " while destroying script.");
- }
- }
-
- function jsdScriptCreated (jsdScript)
- {
- var url = jsdScript.fileName;
- var manager;
-
- if (!(url in console.scriptManagers))
- {
- manager = console.scriptManagers[url] = new ScriptManager(url);
- //dispatchCommand (console.coManagerCreated, { scriptManager: manager });
- }
- else
- {
- manager = console.scriptManagers[url];
- }
-
- manager.onScriptCreated(jsdScript);
- }
-
- function jsdScriptDestroyed (jsdScript)
- {
- if (!(jsdScript.tag in console.scriptWrappers))
- return;
-
- var scriptWrapper = console.scriptWrappers[jsdScript.tag];
- scriptWrapper.scriptManager.onScriptInvalidated(scriptWrapper);
-
- if (scriptWrapper.scriptManager.instances.length == 0 &&
- scriptWrapper.scriptManager.transientCount == 0)
- {
- delete console.scriptManagers[scriptWrapper.scriptManager.url];
- //dispatchCommand (console.coManagerDestroyed,
- // { scriptManager: scriptWrapper.scriptManager });
- }
- }
-
- function jsdExecutionHook (frame, type, rv)
- {
- dd ("execution hook: " + formatFrame(frame));
-
- var hookReturn = jsdIExecutionHook.RETURN_CONTINUE;
-
- if (!console.initialized)
- return hookReturn;
-
-
- if (!ASSERT(!("frames" in console),
- "Execution hook called while stopped") ||
- frame.isNative ||
- !ASSERT(frame.script, "Execution hook called with no script") ||
- frame.script.fileName == MSG_VAL_CONSOLE ||
- !ASSERT(!(frame.script.flags & SCRIPT_NODEBUG),
- "Stopped in a script marked as don't debug") ||
- !ASSERT(isURLVenkman(frame.script.fileName) ||
- !isURLFiltered(frame.script.fileName),
- "stopped in a filtered URL"))
- {
- return hookReturn;
- }
-
- var frames = new Array();
- var prevFrame = frame;
- var hasDisabledFrame = false;
-
- while (prevFrame)
- {
- frames.push(prevFrame);
- prevFrame = prevFrame.callingFrame;
- }
-
- var targetWindow = null;
- var wasModal = false;
- var cx;
-
- try
- {
- cx = frame.executionContext;
- }
- catch (ex)
- {
- dd ("no context");
- cx = null;
- }
-
- var targetWasEnabled = true;
- var debuggerWasEnabled = console.baseWindow.enabled;
- console.baseWindow.enabled = true;
-
- if (!ASSERT(cx, "no cx in execution hook"))
- return hookReturn;
-
- var glob = cx.globalObject;
- if (!ASSERT(glob, "no glob in execution hook"))
- return hookReturn;
-
- console.targetWindow = getBaseWindowFromWindow(glob.getWrappedValue());
- targetWasEnabled = console.targetWindow.enabled;
- if (console.targetWindow != console.baseWindow)
- {
- cx.scriptsEnabled = false;
- console.targetWindow.enabled = false;
- }
-
- try
- {
- //dd ("debug trap " + formatFrame(frame));
- hookReturn = debugTrap(frames, type, rv);
- //dd ("debug trap returned " + hookReturn);
- }
- catch (ex)
- {
- display (MSG_ERR_INTERNAL_BPT, MT_ERROR);
- display (formatException(ex), MT_ERROR);
- }
-
-
-
- if (console.targetWindow && console.targetWindow != console.baseWindow)
- {
- console.targetWindow.enabled = targetWasEnabled;
- cx.scriptsEnabled = true;
- }
-
- console.baseWindow.enabled = debuggerWasEnabled;
- delete console.frames;
- delete console.targetWindow;
- if ("__exitAfterContinue__" in console)
- window.close();
-
- return hookReturn;
- }
-
- function jsdCallHook (frame, type)
- {
- if (!console.initialized)
- return;
-
- if (type == jsdICallHook.TYPE_FUNCTION_CALL)
- {
- setStopState(false);
- //dd ("Calling: " + frame.functionName);
- }
- else if (type == jsdICallHook.TYPE_FUNCTION_RETURN)
- {
- // we're called *before* the returning frame is popped from the
- // stack, so we want our depth calculation to be off by one.
- var depth = -1;
- var prevFrame = frame;
-
- while (prevFrame)
- {
- depth++;
- prevFrame = prevFrame.callingFrame;
- }
-
-
- //dd ("Returning: " + frame.functionName +
- // ", target depth: " + console._stepOverDepth +
- // ", current depth: " + depth);
-
- if (depth <= console._stepOverDepth)
- {
- //dd ("step over at target depth of " + depth);
- setStopState(true);
- console.jsds.functionHook = null;
- delete console._stepOverDepth;
- }
- }
- }
-
- function jsdErrorHook (message, fileName, line, pos, flags, exception)
- {
- if (!console.initialized || isURLFiltered (fileName))
- return true;
-
- try
- {
- var flagstr;
- flagstr =
- (flags && jsdIErrorHook.REPORT_EXCEPTION) ? "x" : "-";
- flagstr +=
- (flags && jsdIErrorHook.REPORT_STRICT) ? "s" : "-";
-
- //dd ("===\n" + message + "\n" + fileName + "@" +
- // line + ":" + pos + "; " + flagstr);
- var msn = (flags & jsdIErrorHook.REPORT_WARNING) ?
- MSN_ERPT_WARN : MSN_ERPT_ERROR;
-
- if (console.errorMode != EMODE_IGNORE)
- display (getMsg(msn, [message, flagstr, fileName,
- line, pos]), MT_ETRACE);
-
- if (console.errorMode == EMODE_BREAK)
- return false;
-
- return true;
- }
- catch (ex)
- {
- dd ("error in error hook: " + ex);
- }
- return true;
- }
-
- function ScriptManager (url)
- {
- this.url = url;
- this.instances = new Array();
- this.transients = new Object();
- this.transientCount = 0;
- this.disableTransients = isURLFiltered(url);
- }
-
- ScriptManager.prototype.onScriptCreated =
- function smgr_created (jsdScript)
- {
- var instance;
-
- if (!ASSERT(jsdScript.isValid, "invalid script created!"))
- return;
-
- if (this.instances.length != 0)
- instance = this.instances[this.instances.length - 1];
-
- if (!instance || (instance.isSealed && jsdScript.functionName))
- {
- //dd ("instance created for " + jsdScript.fileName);
- instance = new ScriptInstance(this);
- instance.sequence = console.instanceSequence++;
- this.instances.push(instance);
- dispatchCommand (console.coInstanceCreated,
- { scriptInstance: instance });
- }
-
- if ("_lastScriptWrapper" in console)
- {
- if ((console._lastScriptWrapper.scriptManager != this ||
- console._lastScriptWrapper.scriptInstance != instance) &&
- console._lastScriptWrapper.scriptInstance.scriptCount &&
- !console._lastScriptWrapper.scriptInstance.isSealed)
- {
- console._lastScriptWrapper.scriptInstance.seal();
- }
- }
-
- var scriptWrapper = new ScriptWrapper(jsdScript);
- console._lastScriptWrapper = scriptWrapper;
- scriptWrapper.scriptManager = this;
- console.scriptWrappers[jsdScript.tag] = scriptWrapper;
- scriptWrapper.scriptInstance = instance;
-
- if (!instance.isSealed)
- {
- //dd ("function created " + formatScript(jsdScript));
- instance.onScriptCreated (scriptWrapper);
- }
- else
- {
- //dd ("transient created " + formatScript(jsdScript));
- ++this.transientCount;
- if (this.disableTransients)
- jsdScript.flags |= SCRIPT_NODEBUG | SCRIPT_NOPROFILE;
-
- this.transients[jsdScript.tag] = scriptWrapper;
- scriptWrapper.functionName = MSG_VAL_EVSCRIPT;
- //dispatch ("hook-transient-script", { scriptWrapper: scriptWrapper });
- }
- }
-
- ScriptManager.prototype.onScriptInvalidated =
- function smgr_invalidated (scriptWrapper)
- {
- //dd ("script invalidated");
-
- delete console.scriptWrappers[scriptWrapper.tag];
- if (scriptWrapper.tag in this.transients)
- {
- //dd ("transient destroyed " + formatScript(scriptWrapper.jsdScript));
- --this.transientCount;
- delete this.transients[scriptWrapper.tag];
- //dispatch ("hook-script-invalidated", { scriptWrapper: scriptWrapper });
- }
- else
- {
- //dd ("function destroyed " + formatScript(scriptWrapper.jsdScript));
- scriptWrapper.scriptInstance.onScriptInvalidated(scriptWrapper);
- //dispatch ("hook-script-invalidated", { scriptWrapper: scriptWrapper });
-
- if (scriptWrapper.scriptInstance.scriptCount == 0)
- {
- var i = arrayIndexOf(this.instances, scriptWrapper.scriptInstance);
- arrayRemoveAt(this.instances, i);
- dispatchCommand (console.coInstanceDestroyed,
- { scriptInstance: scriptWrapper.scriptInstance });
- }
- }
- }
-
- ScriptManager.prototype.__defineGetter__ ("sourceText", smgr_sourcetext);
- function smgr_sourcetext()
- {
- return this.instances[this.instances.length - 1].sourceText;
- }
-
- ScriptManager.prototype.__defineGetter__ ("lineMap", smgr_linemap);
- function smgr_linemap()
- {
- return this.instances[this.instances.length - 1].lineMap;
- }
-
- ScriptManager.prototype.getInstanceBySequence =
- function smgr_bysequence (seq)
- {
- for (var i = 0; i < this.instances.length; ++i)
- {
- if (this.instances[i].sequence == seq)
- return this.instances[i];
- }
-
- return null;
- }
-
- ScriptManager.prototype.isLineExecutable =
- function smgr_isexe (line)
- {
- for (var i in this.instances)
- {
- if (this.instances[i].isLineExecutable(line))
- return true;
- }
-
- return false;
- }
-
- ScriptManager.prototype.hasBreakpoint =
- function smgr_hasbp (line)
- {
- for (var i in this.instances)
- {
- if (this.instances[i].hasBreakpoint(line))
- return true;
- }
-
- return false;
- }
-
- ScriptManager.prototype.setBreakpoint =
- function smgr_break (line, parentBP, props)
- {
- var found = false;
-
- for (var i in this.instances)
- found |= this.instances[i].setBreakpoint(line, parentBP, props);
-
- return found;
- }
-
- ScriptManager.prototype.clearBreakpoint =
- function smgr_break (line)
- {
- var found = false;
-
- for (var i in this.instances)
- found |= this.instances[i].clearBreakpoint(line);
-
- return found;
- }
-
- ScriptManager.prototype.hasFutureBreakpoint =
- function smgr_hasbp (line)
- {
- var key = this.url + "#" + line;
- return (key in console.fbreaks);
- }
-
- ScriptManager.prototype.getFutureBreakpoint =
- function smgr_getfbp (line)
- {
- return getFutureBreakpoint (this.url, line);
- }
-
- ScriptManager.prototype.noteFutureBreakpoint =
- function smgr_fbreak (line, state)
- {
- for (var i in this.instances)
- {
- if (this.instances[i]._lineMapInited)
- {
- if (state)
- {
- arrayOrFlag (this.instances[i]._lineMap, line - 1, LINE_FBREAK);
- }
- else
- {
- arrayAndFlag (this.instances[i]._lineMap, line - 1,
- ~LINE_FBREAK);
- }
- }
- }
- }
-
- function ScriptInstance (manager)
- {
- this.scriptManager = manager;
- this.url = manager.url;
- this.creationDate = new Date();
- this.topLevel = null;
- this.functions = new Object();
- this.nestLevel = 0;
- this.isSealed = false;
- this.scriptCount = 0;
- this.breakpointCount = 0;
- this.disabledScripts = 0;
- this._lineMap = new Array();
- this._lineMapInited = false;
- }
-
- ScriptInstance.prototype.scanForMetaComments =
- function si_scan (start)
- {
- const CHUNK_SIZE = 500;
- const CHUNK_DELAY = 100;
-
- var scriptInstance = this;
- var sourceText = this.sourceText;
-
- function onSourceLoaded(result)
- {
- if (result == Components.results.NS_OK)
- scriptInstance.scanForMetaComments();
- };
-
- if (!sourceText.isLoaded)
- {
- sourceText.loadSource(onSourceLoaded);
- return;
- }
-
- if (typeof start == "undefined")
- start = 0;
-
- var end = Math.min (sourceText.lines.length, start + CHUNK_SIZE);
- var obj = new Object();
-
- for (var i = start; i < end; ++i)
- {
- var ary = sourceText.lines[i].match (/\/\/@(\S+)(.*)/);
- if (ary && ary[1] in console.metaDirectives && !(ary[1] in obj))
- {
- try
- {
- console.metaDirectives[ary[1]](scriptInstance, i + 1, ary);
- }
- catch (ex)
- {
- display (getMsg(MSN_ERR_META_FAILED, [ary[1], this.url, i + 1]),
- MT_ERROR);
- display (formatException (ex), MT_ERROR);
- }
- }
- }
-
- if (i != sourceText.lines.length)
- setTimeout (this.scanForMetaComments, CHUNK_DELAY, i);
- }
-
- ScriptInstance.prototype.seal =
- function si_seal ()
- {
- this.sealDate = new Date();
- this.isSealed = true;
-
- if (isURLFiltered(this.url))
- {
- this.disabledScripts = 1;
- var nada = SCRIPT_NODEBUG | SCRIPT_NOPROFILE;
- if (this.topLevel && this.topLevel.isValid)
- this.topLevel.jsdScript.flags |= nada;
-
- for (var f in this.functions)
- {
- if (this.functions[f].jsdScript.isValid)
- this.functions[f].jsdScript.flags |= nada;
- ++this.disabledScripts;
- }
- }
-
- dispatch ("hook-script-instance-sealed", { scriptInstance: this });
- }
-
- ScriptInstance.prototype.onScriptCreated =
- function si_created (scriptWrapper)
- {
- var tag = scriptWrapper.jsdScript.tag;
-
- if (scriptWrapper.functionName)
- {
- this.functions[tag] = scriptWrapper;
- }
- else
- {
- this.topLevel = scriptWrapper;
- scriptWrapper.functionName = MSG_VAL_TLSCRIPT;
- scriptWrapper.addToLineMap(this._lineMap);
- //var dummy = scriptWrapper.sourceText;
- this.seal();
- }
-
- ++this.scriptCount;
- }
-
- ScriptInstance.prototype.onScriptInvalidated =
- function si_invalidated (scriptWrapper)
- {
- //dd ("script invalidated");
- scriptWrapper.clearBreakpoints();
- --this.scriptCount;
- }
-
- ScriptInstance.prototype.__defineGetter__ ("sourceText", si_gettext);
- function si_gettext ()
- {
- if (!("_sourceText" in this))
- this._sourceText = new SourceText (this);
-
- return this._sourceText;
- }
-
- ScriptInstance.prototype.__defineGetter__ ("lineMap", si_linemap);
- function si_linemap()
- {
- if (!this._lineMapInited)
- {
- if (this.topLevel && this.topLevel.jsdScript.isValid)
- this.topLevel.addToLineMap(this._lineMap);
-
- for (var i in this.functions)
- {
- if (this.functions[i].jsdScript.isValid)
- this.functions[i].addToLineMap(this._lineMap);
- }
-
- for (var fbp in console.fbreaks)
- {
- var fbreak = console.fbreaks[fbp];
- if (fbreak.url == this.url)
- arrayOrFlag (this._lineMap, fbreak.lineNumber - 1, LINE_FBREAK);
- }
-
- this._lineMapInited = true;
- }
-
- return this._lineMap;
- }
-
- ScriptInstance.prototype.isLineExecutable =
- function si_isexe (line)
- {
- if (this.topLevel && this.topLevel.jsdScript.isValid &&
- this.topLevel.jsdScript.isLineExecutable (line, PCMAP_SOURCETEXT))
- {
- return true;
- }
-
- for (var f in this.functions)
- {
- var jsdScript = this.functions[f].jsdScript;
- if (line >= jsdScript.baseLineNumber &&
- line <= jsdScript.baseLineNumber + jsdScript.lineExtent &&
- jsdScript.isLineExecutable (line, PCMAP_SOURCETEXT))
- {
- return true;
- }
- }
-
- return false;
- }
-
- ScriptInstance.prototype.hasBreakpoint =
- function si_hasbp (line)
- {
- return Boolean (this.getBreakpoint(line));
- }
-
- ScriptInstance.prototype.getBreakpoint =
- function si_getbp (line)
- {
- for (var b in console.breaks)
- {
- if (console.breaks[b].scriptWrapper.scriptInstance == this)
- {
- if (typeof line == "undefined")
- return true;
-
- var jsdScript = console.breaks[b].scriptWrapper.jsdScript;
- if (jsdScript.pcToLine(console.breaks[b].pc, PCMAP_SOURCETEXT) ==
- line)
- {
- return console.breaks[b];
- }
- }
- }
-
- return false;
- }
-
- ScriptInstance.prototype.setBreakpoint =
- function si_setbp (line, parentBP, props)
- {
- function setBP (scriptWrapper)
- {
- if (!scriptWrapper.jsdScript.isValid)
- return false;
-
- var jsdScript = scriptWrapper.jsdScript;
-
- if (line >= jsdScript.baseLineNumber &&
- line <= jsdScript.baseLineNumber + jsdScript.lineExtent &&
- (jsdScript.isLineExecutable (line, PCMAP_SOURCETEXT) ||
- jsdScript.baseLineNumber == line))
- {
- var pc = jsdScript.lineToPc(line, PCMAP_SOURCETEXT);
- scriptWrapper.setBreakpoint(pc, parentBP, props);
- return true;
- }
- return false;
- };
-
- var found;
-
- if (this.topLevel)
- found = setBP (this.topLevel);
- for (var f in this.functions)
- found |= setBP (this.functions[f]);
-
- if (this._lineMapInited && found)
- arrayOrFlag(this._lineMap, line - 1, LINE_BREAK);
-
- return found;
- }
-
- ScriptInstance.prototype.clearBreakpoint =
- function si_setbp (line)
- {
- var found = false;
-
- function clearBP (scriptWrapper)
- {
- var jsdScript = scriptWrapper.jsdScript;
- if (!jsdScript.isValid)
- return;
-
- var pc = jsdScript.lineToPc(line, PCMAP_SOURCETEXT);
- if (line >= jsdScript.baseLineNumber &&
- line <= jsdScript.baseLineNumber + jsdScript.lineExtent &&
- scriptWrapper.hasBreakpoint(pc))
- {
- found |= scriptWrapper.clearBreakpoint(pc);
- }
- };
-
- if (this._lineMapInited)
- arrayAndFlag(this._lineMap, line - 1, ~LINE_BREAK);
-
- if (this.topLevel)
- clearBP (this.topLevel);
-
- for (var f in this.functions)
- clearBP (this.functions[f]);
-
- return found;
- }
-
- ScriptInstance.prototype.getScriptWrapperAtLine =
- function si_getscript (line)
- {
- var targetScript = null;
- var scriptWrapper;
-
- if (this.topLevel)
- {
- scriptWrapper = this.topLevel;
- if (line >= scriptWrapper.jsdScript.baseLineNumber &&
- line <= scriptWrapper.jsdScript.baseLineNumber +
- scriptWrapper.jsdScript.lineExtent)
- {
- targetScript = scriptWrapper;
- }
- }
-
- for (var f in this.functions)
- {
- scriptWrapper = this.functions[f];
- if ((line >= scriptWrapper.jsdScript.baseLineNumber &&
- line <= scriptWrapper.jsdScript.baseLineNumber +
- scriptWrapper.jsdScript.lineExtent) &&
- (!targetScript ||
- scriptWrapper.jsdScript.lineExtent <
- targetScript.jsdScript.lineExtent))
- {
- targetScript = scriptWrapper;
- }
- }
-
- return targetScript;
- }
-
- ScriptInstance.prototype.containsScriptTag =
- function si_contains (tag)
- {
- return ((this.topLevel && this.topLevel.tag == tag) ||
- (tag in this.functions));
- }
-
- ScriptInstance.prototype.guessFunctionNames =
- function si_guessnames ()
- {
- var sourceLines = this._sourceText.lines;
- var context = console.prefs["guessContext"];
- var pattern = new RegExp (console.prefs["guessPattern"]);
- var scanText;
-
- function getSourceContext (end)
- {
- var startLine = end - context;
- if (startLine < 0)
- startLine = 0;
-
- var text = "";
-
- for (i = startLine; i <= targetLine; ++i)
- text += String(sourceLines[i]);
-
- var pos = text.lastIndexOf ("function");
- if (pos != -1)
- text = text.substring(0, pos);
-
- return text;
- };
-
- for (var i in this.functions)
- {
- var scriptWrapper = this.functions[i];
- if (scriptWrapper.jsdScript.functionName != "anonymous")
- continue;
-
- var targetLine = scriptWrapper.jsdScript.baseLineNumber;
- if (targetLine > sourceLines.length)
- {
- dd ("not enough source to guess function at line " + targetLine);
- return;
- }
-
- scanText = getSourceContext(targetLine);
- var ary = scanText.match (pattern);
- if (ary)
- {
- if ("charset" in this._sourceText)
- ary[1] = toUnicode(ary[1], this._sourceText.charset);
-
- scriptWrapper.functionName = getMsg(MSN_FMT_GUESSEDNAME, ary[1]);
- }
- else
- {
- if ("guessFallback" in console)
- {
- var name = console.guessFallback(scriptWrapper, scanText);
- if (name)
- {
- scriptWrapper.functionName = getMsg(MSN_FMT_GUESSEDNAME,
- name);
- }
- }
- }
- }
-
- dispatch ("hook-guess-complete", { scriptInstance: this });
- }
-
- function ScriptWrapper (jsdScript)
- {
- this.jsdScript = jsdScript;
- this.tag = jsdScript.tag;
- this.functionName = jsdScript.functionName;
- this.breakpointCount = 0;
- this._lineMap = null;
- this.breaks = new Object();
- }
-
- ScriptWrapper.prototype.__defineGetter__ ("sourceText", sw_getsource);
- function sw_getsource ()
- {
- if (!("_sourceText" in this))
- {
- if (!this.jsdScript.isValid)
- return null;
- this._sourceText = new PPSourceText(this);
- }
-
- return this._sourceText;
- }
-
- ScriptWrapper.prototype.__defineGetter__ ("lineMap", sw_linemap);
- function sw_linemap ()
- {
- if (!this._lineMap)
- this.addToLineMap(this._lineMap);
-
- return this._lineMap;
- }
-
- ScriptWrapper.prototype.hasBreakpoint =
- function sw_hasbp (pc)
- {
- var key = this.jsdScript.tag + ":" + pc;
- return key in console.breaks;
- }
-
- ScriptWrapper.prototype.getBreakpoint =
- function sw_hasbp (pc)
- {
- var key = this.jsdScript.tag + ":" + pc;
- if (key in console.breaks)
- return console.breaks[key];
-
- return null;
- }
-
- ScriptWrapper.prototype.setBreakpoint =
- function sw_setbp (pc, parentBP, props)
- {
- var key = this.jsdScript.tag + ":" + pc;
-
- //dd ("setting breakpoint in " + this.functionName + " " + key);
-
- if (key in console.breaks)
- return null;
-
- var brk = new BreakInstance (parentBP, this, pc);
- if (props)
- brk.setProperties(props);
-
- console.breaks[key] = brk;
- this.breaks[key] = brk;
-
- if (parentBP)
- {
- parentBP.childrenBP[key] = brk;
- brk.lineNumber = parentBP.lineNumber;
- brk.url = parentBP.url;
- }
-
- if ("_sourceText" in this)
- {
- var line = this.jsdScript.pcToLine(brk.pc, PCMAP_PRETTYPRINT);
- arrayOrFlag (this._sourceText.lineMap, line - 1, LINE_BREAK);
- }
-
- ++this.scriptInstance.breakpointCount;
- ++this.breakpointCount;
-
- if (this.scriptInstance._lineMapInited)
- {
- line = this.jsdScript.pcToLine (pc, PCMAP_SOURCETEXT);
- arrayOrFlag (this.scriptInstance._lineMap, line - 1, LINE_BREAK);
- }
-
- dispatch ("hook-break-set", { breakWrapper: brk });
-
- return brk;
- }
-
- ScriptWrapper.prototype.clearBreakpoints =
- function sw_clearbps ()
- {
- var found = false;
-
- for (b in this.breaks)
- found |= this.clearBreakpoint(this.breaks[b].pc);
-
- return found;
- }
-
- ScriptWrapper.prototype.clearBreakpoint =
- function sw_clearbp (pc)
- {
- var key = this.jsdScript.tag + ":" + pc;
- if (!(key in console.breaks))
- return false;
-
- var brk = console.breaks[key];
-
- if ("propsWindow" in brk)
- brk.propsWindow.close();
-
- delete console.breaks[key];
- delete this.breaks[key];
-
- if (brk.parentBP)
- delete brk.parentBP.childrenBP[key];
-
- var line;
-
- if ("_sourceText" in this && this.jsdScript.isValid)
- {
- line = this.jsdScript.pcToLine(brk.pc, PCMAP_PRETTYPRINT);
- this._sourceText.lineMap[line - 1] &= ~LINE_BREAK;
- }
-
- --this.scriptInstance.breakpointCount;
- --this.breakpointCount;
-
- if (this.scriptInstance._lineMapInited)
- {
- if (this.jsdScript.isValid)
- {
- line = this.jsdScript.pcToLine (pc, PCMAP_SOURCETEXT);
- if (!this.scriptInstance.hasBreakpoint(line))
- this.scriptInstance._lineMap[line - 1] &= ~LINE_BREAK;
- }
- else
- {
- /* script is gone, no way to find out where the break actually
- * was, so we have to redo the whole map. */
- this.scriptInstance._lineMapInited = false;
- this.scriptInstance._lineMap.length = 0;
- var dummy = this.scriptInstance.lineMap;
- }
- }
-
- dispatch ("hook-break-clear", { breakWrapper: brk });
-
- if (this.jsdScript.isValid)
- this.jsdScript.clearBreakpoint (pc);
-
- return true;
- }
-
- ScriptWrapper.prototype.addToLineMap =
- function sw_addmap (lineMap)
- {
- var jsdScript = this.jsdScript;
- var end = jsdScript.baseLineNumber + jsdScript.lineExtent;
- for (var i = jsdScript.baseLineNumber; i < end; ++i)
- {
- if (jsdScript.isLineExecutable(i, PCMAP_SOURCETEXT))
- arrayOrFlag (lineMap, i - 1, LINE_BREAKABLE);
- }
-
- for (i in this.breaks)
- {
- var line = jsdScript.pcToLine(this.breaks[i].pc, PCMAP_SOURCETEXT);
- arrayOrFlag (lineMap, line - 1, LINE_BREAK);
- }
- }
-
- function getScriptWrapper(jsdScript)
- {
- if (!ASSERT(jsdScript, "getScriptWrapper: null jsdScript"))
- return null;
-
- var tag = jsdScript.tag;
- if (tag in console.scriptWrappers)
- return console.scriptWrappers[tag];
-
- dd ("Can't find a wrapper for " + formatScript(jsdScript));
- return null;
- }
-
- function BreakInstance (parentBP, scriptWrapper, pc)
- {
- this._enabled = true;
- this.parentBP = parentBP;
- this.scriptWrapper = scriptWrapper;
- this.pc = pc;
- this.url = scriptWrapper.jsdScript.fileName;
- this.lineNumber = scriptWrapper.jsdScript.pcToLine (pc, PCMAP_SOURCETEXT);
- this.oneTime = false;
- this.triggerCount = 0;
-
- scriptWrapper.jsdScript.setBreakpoint (pc);
- }
-
- BreakInstance.prototype.__defineGetter__ ("jsdURL", bi_getURL);
- function bi_getURL ()
- {
- return ("x-jsd:break?url=" + encodeURIComponent(this.url) +
- "&lineNumber=" + this.lineNumber +
- "&conditionEnabled=" + this.conditionEnabled +
- "&condition=" + encodeURIComponent(this.condition) +
- "&passExceptions=" + this.passExceptions +
- "&logResult=" + this.logResult +
- "&resultAction=" + this.resultAction +
- "&enabled=" + this.enabled);
- }
-
- BreakInstance.prototype.getProperties =
- function bi_getprops()
- {
- var rv = new Object();
-
- rv.enabled = this._enabled;
- if ("_conditionEnabled" in this)
- rv.conditionEnabled = this._conditionEnabled;
- if ("_condition" in this)
- rv.condition = this._condition;
- if ("_passExceptions" in this)
- rv.passExceptions = this._passExceptions;
- if ("_logResult" in this)
- rv.logResult = this._logResult;
- if ("_resultAction" in this)
- rv.resultAction = this._resultAction;
-
- return rv;
- }
-
- BreakInstance.prototype.setProperties =
- function bi_setprops(obj)
- {
- for (var p in obj)
- {
- if (p.search(/pc|url|lineNumber/) == -1)
- this[p] = obj[p];
- }
-
- if ("propsWindow" in this)
- this.propsWindow.populateFromBreakpoint();
- }
-
- BreakInstance.prototype.clearBreakpoint =
- function bi_clear()
- {
- this.scriptWrapper.clearBreakpoint(this.pc);
- }
-
- BreakInstance.prototype.__defineGetter__ ("enabled", bi_getEnabled);
- function bi_getEnabled ()
- {
- return this._enabled;
- }
-
- BreakInstance.prototype.__defineSetter__ ("enabled", bi_setEnabled);
- function bi_setEnabled (state)
- {
- if (state != this._enabled)
- {
- this._enabled = state;
- if (state)
- this.scriptWrapper.jsdScript.setBreakpoint(this.pc);
- else
- this.scriptWrapper.jsdScript.clearBreakpoint(this.pc);
- }
-
- return state;
- }
-
- BreakInstance.prototype.__defineGetter__ ("conditionEnabled", bi_getCondEnabled);
- function bi_getCondEnabled ()
- {
- if ("_conditionEnabled" in this)
- return this._conditionEnabled;
-
- if (this.parentBP)
- return this.parentBP.conditionEnabled;
-
- return false;
- }
-
- BreakInstance.prototype.__defineSetter__ ("conditionEnabled", bi_setCondEnabled);
- function bi_setCondEnabled (state)
- {
- if (this.parentBP)
- return this.parentBP.conditionEnabled = state;
-
- return this._conditionEnabled = state;
- }
-
- BreakInstance.prototype.__defineGetter__ ("condition", bi_getCondition);
- function bi_getCondition ()
- {
- if ("_condition" in this)
- return this._condition;
-
- if (this.parentBP)
- return this.parentBP.condition;
-
- return "";
- }
-
- BreakInstance.prototype.__defineSetter__ ("condition", bi_setCondition);
- function bi_setCondition (value)
- {
- if (this.parentBP)
- return this.parentBP.condition = value;
-
- return this._condition = value;
- }
-
-
- BreakInstance.prototype.__defineGetter__ ("passExceptions", bi_getException);
- function bi_getException ()
- {
- if ("_passExceptions" in this)
- return this._passExceptions;
-
- if (this.parentBP)
- return this.parentBP.passExceptions;
-
- return false;
- }
-
- BreakInstance.prototype.__defineSetter__ ("passExceptions", bi_setException);
- function bi_setException (state)
- {
- if (this.parentBP)
- return this.parentBP.passExceptions = state;
-
- return this._passExceptions = state;
- }
-
-
- BreakInstance.prototype.__defineGetter__ ("logResult", bi_getLogResult);
- function bi_getLogResult ()
- {
- if ("_logResult" in this)
- return this._logResult;
-
- if (this.parentBP)
- return this.parentBP.logResult;
-
- return false;
- }
-
- BreakInstance.prototype.__defineSetter__ ("logResult", bi_setLogResult);
- function bi_setLogResult (state)
- {
- if (this.parentBP)
- return this.parentBP.logResult = state;
-
- return this._logResult = state;
- }
-
-
- BreakInstance.prototype.__defineGetter__ ("resultAction", bi_getResultAction);
- function bi_getResultAction ()
- {
- if ("_resultAction" in this)
- return this._resultAction;
-
- if (this.parentBP)
- return this.parentBP.resultAction;
-
- return BREAKPOINT_STOPALWAYS;
- }
-
- BreakInstance.prototype.__defineSetter__ ("resultAction", bi_setResultAction);
- function bi_setResultAction (state)
- {
- if (this.parentBP)
- return this.parentBP.resultAction = state;
-
- return this._resultAction = state;
- }
-
- function FutureBreakpoint (url, lineNumber)
- {
- this.url = url;
- this.lineNumber = lineNumber;
- this.enabled = true;
- this.childrenBP = new Object();
- this.conditionEnabled = false;
- this.condition = "";
- this.passExceptions = false;
- this.logResult = false;
- this.resultAction = BREAKPOINT_STOPALWAYS;
- }
-
- FutureBreakpoint.prototype.__defineGetter__ ("jsdURL", fb_getURL);
- function fb_getURL ()
- {
- return ("x-jsd:fbreak?url=" + encodeURIComponent(this.url) +
- "&lineNumber=" + this.lineNumber +
- "&conditionEnabled=" + this.conditionEnabled +
- "&condition=" + encodeURIComponent(this.condition) +
- "&passExceptions=" + this.passExceptions +
- "&logResult=" + this.logResult +
- "&resultAction=" + this.resultAction +
- "&enabled=" + this.enabled);
- }
-
-
- FutureBreakpoint.prototype.getProperties =
- function fb_getprops()
- {
- var rv = new Object();
-
- rv.conditionEnabled = this.conditionEnabled;
- rv.condition = this.condition;
- rv.passExceptions = this.passExceptions;
- rv.logResult = this.logResult;
- rv.resultAction = this.resultAction;
-
- return rv;
- }
-
- FutureBreakpoint.prototype.setProperties =
- function fb_setprops(obj)
- {
- for (var p in obj)
- {
- if (p.search(/url|lineNumber|childrenBP/) == -1)
- this[p] = obj[p];
- }
-
- if ("propsWindow" in this)
- this.propsWindow.populateFromBreakpoint();
- }
-
- FutureBreakpoint.prototype.clearFutureBreakpoint =
- function fb_clear ()
- {
- clearFutureBreakpoint (this.url, this.lineNumber);
- }
-
- FutureBreakpoint.prototype.resetInstances =
- function fb_reseti ()
- {
- for (var url in console.scriptManagers)
- {
- if (url.indexOf(this.url) != -1)
- console.scriptManagers[url].setBreakpoint(this.lineNumber);
- }
- }
-
- FutureBreakpoint.prototype.clearInstances =
- function fb_cleari ()
- {
- for (var url in console.scriptManagers)
- {
- if (url.indexOf(this.url) != -1)
- console.scriptManagers[url].clearBreakpoint(this.lineNumber);
- }
- }
-
- function testBreakpoint(currentFrame, rv)
- {
- var tag = currentFrame.script.tag;
- if (!(tag in console.scriptWrappers))
- return -1;
-
- var scriptWrapper = console.scriptWrappers[tag];
- var breakpoint = scriptWrapper.getBreakpoint(currentFrame.pc);
- if (!ASSERT(breakpoint, "can't find breakpoint for " +
- formatFrame(currentFrame)))
- {
- return -1;
- }
-
- if (!ASSERT(breakpoint.enabled, "stopped at a disabled breakpoint?"))
- return RETURN_CONTINUE;
-
- ++breakpoint.triggerCount;
- if ("propsWindow" in breakpoint)
- breakpoint.propsWindow.onBreakpointTriggered();
-
- if (breakpoint.oneTime)
- scriptWrapper.clearBreakpoint(currentFrame.pc);
-
- if (breakpoint.conditionEnabled && breakpoint.condition)
- {
- var result = new Object();
- var script = "var __trigger__ = function (__count__) {" +
- breakpoint.condition + "}; __trigger__.apply(this, [" +
- breakpoint.triggerCount + "]);";
- if (!currentFrame.eval (script,
- JSD_URL_SCHEME + "breakpoint-condition",
- 1, result))
- {
- /* condition raised an exception */
- if (breakpoint.passExceptions)
- {
- rv.value = result.value;
- return RETURN_THROW;
- }
-
- display (MSG_ERR_CONDITION_FAILED, MT_ERROR);
- display (formatException(result.value.getWrappedValue()), MT_ERROR);
- }
- else
- {
- /* condition executed ok */
- if (breakpoint.logResult)
- {
- display (result.value.stringValue, MT_LOG);
- }
-
- if (breakpoint.resultAction == BREAKPOINT_EARLYRETURN)
- {
- rv.value = result.value;
- return RETURN_VALUE;
- }
-
- if (breakpoint.resultAction == BREAKPOINT_STOPNEVER ||
- (breakpoint.resultAction == BREAKPOINT_STOPTRUE &&
- !result.value.booleanValue))
- {
- return RETURN_CONTINUE;
- }
- }
- }
-
- return -1;
- }
-
- const EMODE_IGNORE = 0;
- const EMODE_TRACE = 1;
- const EMODE_BREAK = 2;
-
- const TMODE_IGNORE = 0;
- const TMODE_TRACE = 1;
- const TMODE_BREAK = 2;
-
- function debugTrap (frames, type, rv)
- {
- var tn = "";
- var retcode = jsdIExecutionHook.RETURN_CONTINUE;
-
- //dd ("debugTrap");
-
- var frame = frames[0];
-
- $ = new Array();
-
- switch (type)
- {
- case jsdIExecutionHook.TYPE_BREAKPOINT:
- var bpResult = testBreakpoint(frame, rv);
- if (bpResult != -1)
- return bpResult;
- tn = MSG_VAL_BREAKPOINT;
- break;
- case jsdIExecutionHook.TYPE_DEBUG_REQUESTED:
- tn = MSG_VAL_DEBUG;
- break;
- case jsdIExecutionHook.TYPE_DEBUGGER_KEYWORD:
- tn = MSG_VAL_DEBUGGER;
- break;
- case jsdIExecutionHook.TYPE_THROW:
- dd (dumpObjectTree(rv));
- display (getMsg(MSN_EXCEPTION_TRACE,
- [rv.value.stringValue, formatFrame(frame)]),
- MT_ETRACE);
- if (rv.value.jsClassName == "Error")
- display (formatProperty(rv.value.getProperty("message")),
- MT_EVAL_OUT);
-
- if (console.throwMode != TMODE_BREAK)
- return jsdIExecutionHook.RETURN_CONTINUE_THROW;
-
- console.currentException = rv.value;
- retcode = jsdIExecutionHook.RETURN_CONTINUE_THROW;
-
- tn = MSG_VAL_THROW;
- break;
- case jsdIExecutionHook.TYPE_INTERRUPTED:
-
- if (!frame.script.functionName &&
- isURLFiltered(frame.script.fileName))
- {
- //dd ("filtered url: " + frame.script.fileName);
- frame.script.flags |= SCRIPT_NOPROFILE | SCRIPT_NODEBUG;
- return retcode;
- }
-
- var line;
- if (console.prefs["prettyprint"])
- line = frame.script.pcToLine (frame.pc, PCMAP_PRETTYPRINT);
- else
- line = frame.line;
- if (console._stepPast ==
- frames.length + frame.script.fileName + line)
- {
- //dd("stepPast: " + console._stepPast);
- return retcode;
- }
-
- delete console._stepPast;
- setStopState(false);
- break;
- default:
- /* don't print stop/cont messages for other types */
- }
-
- console.jsds.functionHook = null;
-
- /* set our default return value */
- console._continueCodeStack.push (retcode);
-
- if (tn)
- display (getMsg(MSN_STOP, tn), MT_STOP);
-
- /* build an array of frames */
- console.frames = frames;
-
- console.trapType = type;
-
- try
- {
- console.jsds.enterNestedEventLoop({onNest: eventLoopNested});
- }
- catch (ex)
- {
- dd ("caught " + ex + " while nested");
- }
-
- /* execution pauses here until someone calls exitNestedEventLoop() */
-
- clearCurrentFrame();
- rv.value = ("currentException" in console) ? console.currentException : null;
-
- delete console.frames;
- delete console.trapType;
- delete console.currentException;
- $ = new Array();
-
- dispatch ("hook-debug-continue");
-
- if (tn)
- display (getMsg(MSN_CONT, tn), MT_CONT);
-
- return console._continueCodeStack.pop();
- }
-
- function eventLoopNested ()
- {
- window.focus();
- window.getAttention();
-
- dispatch ("hook-debug-stop");
- }
-
- function getCurrentFrame()
- {
- if ("frames" in console)
- return console.frames[console._currentFrameIndex];
-
- return null;
- }
-
- function getCurrentFrameIndex()
- {
- if (typeof console._currentFrameIndex == "undefined")
- return -1;
-
- return console._currentFrameIndex;
- }
-
- function setCurrentFrameByIndex (index)
- {
- if (!console.frames)
- throw new BadMojo (ERR_NO_STACK);
-
- ASSERT (index >= 0 && index < console.frames.length, "index out of range");
-
- console._currentFrameIndex = index;
- var cf = console.frames[console._currentFrameIndex];
- dispatch ("set-eval-obj", { jsdValue: cf });
- console.stopFile = (cf.isNative) ? MSG_URL_NATIVE : cf.script.fileName;
- console.stopLine = cf.line;
- delete console._pp_stopLine;
- return cf;
- }
-
- function clearCurrentFrame ()
- {
- if (!console.frames)
- throw new BadMojo (ERR_NO_STACK);
-
- if (console.currentEvalObject instanceof jsdIStackFrame)
- dispatch ("set-eval-obj", { jsdValue: console.jsdConsole });
-
- delete console.stopLine;
- delete console._pp_stopLine;
- delete console.stopFile;
- delete console._currentFrameIndex;
- }
-
- function formatArguments (v)
- {
- if (!v)
- return "";
-
- var ary = new Array();
- var p = new Object();
- v.getProperties (p, {});
- p = p.value;
- for (var i = 0; i < p.length; ++i)
- {
- if (p[i].flags & jsdIProperty.FLAG_ARGUMENT)
- ary.push (getMsg(MSN_FMT_ARGUMENT,
- [p[i].name.stringValue,
- formatValue(p[i].value, FTYPE_SUMMARY)]));
- }
-
- return ary.join (MSG_COMMASP);
- }
-
- function formatFlags (flags)
- {
- var s = "";
-
- if (flags & PROP_ENUMERATE)
- s += MSG_VF_ENUMERABLE;
- if (flags & PROP_READONLY)
- s += MSG_VF_READONLY;
- if (flags & PROP_PERMANENT)
- s += MSG_VF_PERMANENT;
- if (flags & PROP_ALIAS)
- s += MSG_VF_ALIAS;
- if (flags & PROP_ARGUMENT)
- s += MSG_VF_ARGUMENT;
- if (flags & PROP_VARIABLE)
- s += MSG_VF_VARIABLE;
- if (flags & PROP_ERROR)
- s += MSG_VF_ERROR;
- if (flags & PROP_EXCEPTION)
- s += MSG_VF_EXCEPTION;
- if (flags & PROP_HINTED)
- s += MSG_VF_HINTED;
-
- return s;
- }
-
- function formatProperty (p, formatType)
- {
- if (!p)
- throw new BadMojo (ERR_REQUIRED_PARAM, "p");
-
- var s = formatFlags (p.flags);
-
- if (formatType == FTYPE_ARRAY)
- {
- var rv = formatValue (p.value, FTYPE_ARRAY);
- return [p.name.stringValue, rv[1] ? rv[1] : rv[0], rv[2], s];
- }
-
- return getMsg(MSN_FMT_PROPERTY, [s, p.name.stringValue,
- formatValue(p.value)]);
- }
-
- function formatScript (script)
- {
- if (!script)
- throw new BadMojo (ERR_REQUIRED_PARAM, "script");
-
- var functionName;
- if (script.tag in console.scriptWrappers)
- functionName = console.scriptWrappers[script.tag].functionName;
- else
- functionName = script.functionName;
- return getMsg (MSN_FMT_SCRIPT, [functionName, script.fileName]);
- }
-
- function formatFrame (f)
- {
- if (!f)
- throw new BadMojo (ERR_REQUIRED_PARAM, "f");
- var url = (f.isNative) ? MSG_URL_NATIVE : f.script.fileName;
- return getMsg (MSN_FMT_FRAME,
- [f.functionName, formatArguments(f.scope), url, f.line]);
- }
-
- function formatValue (v, formatType)
- {
- if (!v)
- throw new BadMojo (ERR_REQUIRED_PARAM, "v");
-
- if (!(v instanceof jsdIValue))
- throw new BadMojo (ERR_INVALID_PARAM, "v", String(v));
-
- var type;
- var value;
-
- switch (v.jsType)
- {
- case jsdIValue.TYPE_BOOLEAN:
- type = MSG_TYPE_BOOLEAN;
- value = String(v.booleanValue);
- break;
- case jsdIValue.TYPE_DOUBLE:
- type = MSG_TYPE_DOUBLE;
- value = v.doubleValue;
- break;
- case jsdIValue.TYPE_INT:
- type = MSG_TYPE_INT;
- value = v.intValue;
- break;
- case jsdIValue.TYPE_FUNCTION:
- type = MSG_TYPE_FUNCTION;
- value = v.jsFunctionName;
- break;
- case jsdIValue.TYPE_NULL:
- type = MSG_TYPE_NULL;
- value = MSG_TYPE_NULL;
- break;
- case jsdIValue.TYPE_OBJECT:
- if (formatType == FTYPE_STD)
- {
- type = MSG_TYPE_OBJECT;
- value = getMsg(MSN_FMT_OBJECT, String(v.propertyCount));
- }
- else
- {
- if (v.jsClassName)
- if (v.jsClassName == "XPCWrappedNative_NoHelper")
- type = MSG_CLASS_XPCOBJ;
- else
- type = v.jsClassName;
- else
- type = MSG_TYPE_OBJECT;
- value = "{" + String(v.propertyCount) + "}";
- }
- break;
- case jsdIValue.TYPE_STRING:
- type = MSG_TYPE_STRING;
- var strval = v.stringValue;
- if (strval.length > console.prefs["maxStringLength"])
- strval = getMsg(MSN_FMT_LONGSTR, strval.length);
- else
- strval = strval.quote()
- value = strval;
- break;
- case jsdIValue.TYPE_VOID:
- type = MSG_TYPE_VOID;
- value = MSG_TYPE_VOID;
- break;
- default:
- type = MSG_TYPE_UNKNOWN;
- value = MSG_TYPE_UNKNOWN;
- break;
- }
-
- if (formatType == FTYPE_SUMMARY)
- return getMsg (MSN_FMT_VALUE_SHORT, [type, value]);
-
- var className;
- if (v.jsClassName)
- if (v.jsClassName == "XPCWrappedNative_NoHelper")
- /* translate this long, unintuitive, and common class name into
- * something more palatable. */
- className = MSG_CLASS_XPCOBJ;
- else
- className = v.jsClassName;
-
- if (formatType == FTYPE_ARRAY)
- return [type, className, value];
-
- if (className)
- return getMsg (MSN_FMT_VALUE_LONG, [type, v.jsClassName, value]);
-
- return getMsg (MSN_FMT_VALUE_MED, [type, value]);
-
- }
-
- function displayCallStack ()
- {
- for (var i = 0; i < console.frames.length; ++i)
- displayFrame (console.frames[i], i);
- }
-
- function displayProperties (v)
- {
- if (!v)
- throw new BadMojo (ERR_REQUIRED_PARAM, "v");
-
- if (!(v instanceof jsdIValue))
- throw new BadMojo (ERR_INVALID_PARAM, "v", String(v));
-
- var p = new Object();
- v.getProperties (p, {});
- for (var i in p.value) display(formatProperty (p.value[i]), MT_EVAL_OUT);
- }
-
- function displaySourceContext (sourceText, line, contextLines)
- {
- function onSourceLoaded (status)
- {
- if (status == Components.results.NS_OK)
- displaySourceContext (sourceText, line, contextLines);
- }
-
- if (sourceText.isLoaded)
- {
- for (var i = line - contextLines; i <= line + contextLines; ++i)
- {
- if (i > 0 && i < sourceText.lines.length)
- {
- var sourceLine;
- if ("charset" in sourceText)
- {
- sourceLine = toUnicode(sourceText.lines[i - 1],
- sourceText.charset);
- }
- else
- {
- sourceLine = sourceText.lines[i - 1];
- }
-
- display (getMsg(MSN_SOURCE_LINE, [zeroPad (i, 3), sourceLine]),
- i == line ? MT_STEP : MT_SOURCE);
- }
- }
- }
- else
- {
- sourceText.loadSource (onSourceLoaded);
- }
- }
-
- function displayFrame (jsdFrame, idx, showHeader, sourceContext)
- {
- if (typeof idx == "undefined")
- {
- for (idx = 0; idx < console.frames.length; ++idx)
- if (jsdFrame == console.frames[idx])
- break;
-
- if (idx >= console.frames.length)
- idx = MSG_VAL_UNKNOWN;
- }
-
- if (typeof showHeader == "undefined")
- showHeader = true;
-
- if (typeof sourceContext == "undefined")
- sourceContext = null;
-
- display(getMsg(MSN_FMT_FRAME_LINE, [idx, formatFrame(jsdFrame)]), MT_OUTPUT);
-
- if (!jsdFrame.isNative && sourceContext != null)
- {
- var jsdScript = jsdFrame.script;
- var scriptWrapper = getScriptWrapper(jsdScript);
-
- if (!ASSERT(scriptWrapper, "Couldn't get a script wrapper"))
- return;
- if (console.prefs["prettyprint"] && jsdScript.isValid)
- {
- displaySourceContext (scriptWrapper.sourceText,
- jsdScript.pcToLine(jsdFrame.pc,
- PCMAP_PRETTYPRINT),
- sourceContext);
- }
- else
- {
- displaySourceContext (scriptWrapper.scriptInstance.sourceText,
- jsdFrame.line, sourceContext);
- }
- }
- }
-
- function getFutureBreakpoint (urlPattern, lineNumber)
- {
- var key = urlPattern + "#" + lineNumber;
- if (key in console.fbreaks)
- return console.fbreaks[key];
-
- return null;
- }
-
- function setFutureBreakpoint (urlPattern, lineNumber, props)
- {
- var key = urlPattern + "#" + lineNumber;
-
- if (key in console.fbreaks)
- return false;
-
- var url;
-
- for (url in console.scriptManagers)
- {
- if (url == urlPattern)
- console.scriptManagers[url].noteFutureBreakpoint(lineNumber, true);
- }
-
- for (url in console.files)
- {
- if (url == urlPattern)
- console.files[url].noteFutureBreakpoint(lineNumber, true);
- }
-
- var fbreak = new FutureBreakpoint (urlPattern, lineNumber);
- if (props)
- fbreak.setProperties(props);
- console.fbreaks[key] = fbreak;
-
- dispatch ("hook-fbreak-set", { fbreak: fbreak });
-
- return fbreak;
- }
-
- function clearFutureBreakpoint (urlPattern, lineNumber)
- {
- var key = urlPattern + "#" + lineNumber;
- if (!(key in console.fbreaks))
- return false;
-
- var i;
- var fbreak = console.fbreaks[key];
- if ("propsWindow" in fbreak)
- fbreak.propsWindow.close();
-
- delete console.fbreaks[key];
-
- for (i in fbreak.childrenBP)
- fbreak.childrenBP[i].parentBP = null;
-
- var url;
-
- for (url in console.scriptManagers)
- {
- if (url.indexOf(urlPattern) != -1)
- console.scriptManagers[url].noteFutureBreakpoint(lineNumber, false);
- }
-
- for (url in console.files)
- {
- if (url == urlPattern)
- console.files[url].noteFutureBreakpoint(lineNumber, false);
- }
-
- dispatch ("hook-fbreak-clear", { fbreak: fbreak });
-
- return true;
- }
-